//
//  SwiftJSBridging.swift
//  SwiftLua
//
//  Created by xiaerfei on 2019/7/27.
//  Copyright © 2019 xiaerfei. All rights reserved.
//

import UIKit
import UIColor_Hex_Swift
import JavaScriptCore
import yoga

@objc protocol JSUIViewDelegate: JSExport {
//    var subViews:Dictionary<String, Any> { get set }
    init(src:String)
    func background(color:String)
    func add(view:UIView?)
    func flxChild(views:Array<UIView>?)
    func flex(css: String?) -> Void
    func flex(layout:Dictionary<String,String>)
}

@objc protocol JSUILabelDelegate: JSExport {
    init()
    func text(text:String)
    func lineNumber(number:String)
    func textColor(color:String)
    func fontSize(size:String)
    func flex(css: String?) -> Void
    func background(color:String)
    func flex(layout:Dictionary<String,String>)
}
/*
 <View frame="0, 0, sys.contW, sys.contH" css="{justify-content='center', align-items='center'}">
 <Text css="{width=sys.contW/2, height=sys.contW/8}" text="Hello World" fontSize="18" textAlign="TextAlign.CENTER"></Text>
 </View>
 */


@objc public class LVUIView: UIView, JSUIViewDelegate {
    func add(view: UIView?) {
        if view != nil {
            self.addSubview(view!)
        }
    }
    
    var context: JSContext? = nil
//    dynamic var subViews: Dictionary<String, Any> = [:]
    override public init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required convenience init(src: String) {
        self.init(frame: .zero)
    }
    
    required convenience init() {
        self.init(frame: .zero)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

@objc public class LVUILabel: UILabel, JSUILabelDelegate {
    public override init(frame: CGRect) {
        super.init(frame: frame)
    }
    required convenience init() {
        self.init(frame: .zero)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func text(text: String) {
        self.text = text
    }
    
    func lineNumber(number: String) {
        self.numberOfLines = Int(number) ?? 1
    }
    
    func textColor(color: String) {
        self.textColor = UIColor(color)
    }
    func fontSize(size: String) {
        let double = Double(size)
        //返回的double是个可选值，所以需要给个默认值或者用!强制解包
        let float = CGFloat(double ?? 0)
        self.font = UIFont.systemFont(ofSize: float)
    }
}

extension LVUIView {
    func flxChild(views:Array<UIView>?) -> Void {
        if views != nil && views!.count > 0 {
            var childs:Array<JUFLXNode> = []
            for view in views! {
                childs.append(view.ju_flxNode())
            }
            self.ju_flxNode()?.childNodes = childs
        }
    }
}

extension UIView {
    @objc func flex(css: String?) -> Void {
        if css != nil {
            self.ju_flxNode()?.bindingInlineCSS(css!)
        }
    }
    @objc func background(color: String) {
        self.backgroundColor = UIColor(color)
    }
    /*
     @property (nonatomic, readwrite, assign) YGDirection direction;
     @property (nonatomic, readwrite, assign) YGFlexDirection flexDirection;
     @property (nonatomic, readwrite, assign) YGJustify justifyContent;
     @property (nonatomic, readwrite, assign) YGAlign alignContent;
     @property (nonatomic, readwrite, assign) YGAlign alignItems;
     @property (nonatomic, readwrite, assign) YGAlign alignSelf;
     @property (nonatomic, readwrite, assign) YGPositionType position;
     @property (nonatomic, readwrite, assign) YGWrap flexWrap;
     @property (nonatomic, readwrite, assign) YGOverflow overflow;
     @property (nonatomic, readwrite, assign) YGDisplay display;
     
     @property (nonatomic, readwrite, assign) CGFloat flexGrow;
     @property (nonatomic, readwrite, assign) CGFloat flexShrink;
     @property (nonatomic, readwrite, assign) YGValue flexBasis;
     
     @property (nonatomic, readwrite, assign) YGValue left;
     @property (nonatomic, readwrite, assign) YGValue top;
     @property (nonatomic, readwrite, assign) YGValue right;
     @property (nonatomic, readwrite, assign) YGValue bottom;
     @property (nonatomic, readwrite, assign) YGValue start;
     @property (nonatomic, readwrite, assign) YGValue end;
     
     @property (nonatomic, readwrite, assign) YGValue marginLeft;
     @property (nonatomic, readwrite, assign) YGValue marginTop;
     @property (nonatomic, readwrite, assign) YGValue marginRight;
     @property (nonatomic, readwrite, assign) YGValue marginBottom;
     @property (nonatomic, readwrite, assign) YGValue marginStart;
     @property (nonatomic, readwrite, assign) YGValue marginEnd;
     @property (nonatomic, readwrite, assign) YGValue marginHorizontal;
     @property (nonatomic, readwrite, assign) YGValue marginVertical;
     @property (nonatomic, readwrite, assign) YGValue margin;
     
     @property (nonatomic, readwrite, assign) YGValue paddingLeft;
     @property (nonatomic, readwrite, assign) YGValue paddingTop;
     @property (nonatomic, readwrite, assign) YGValue paddingRight;
     @property (nonatomic, readwrite, assign) YGValue paddingBottom;
     @property (nonatomic, readwrite, assign) YGValue paddingStart;
     @property (nonatomic, readwrite, assign) YGValue paddingEnd;
     @property (nonatomic, readwrite, assign) YGValue paddingHorizontal;
     @property (nonatomic, readwrite, assign) YGValue paddingVertical;
     @property (nonatomic, readwrite, assign) YGValue padding;
     
     @property (nonatomic, readwrite, assign) CGFloat borderLeftWidth;
     @property (nonatomic, readwrite, assign) CGFloat borderTopWidth;
     @property (nonatomic, readwrite, assign) CGFloat borderRightWidth;
     @property (nonatomic, readwrite, assign) CGFloat borderBottomWidth;
     @property (nonatomic, readwrite, assign) CGFloat borderStartWidth;
     @property (nonatomic, readwrite, assign) CGFloat borderEndWidth;
     @property (nonatomic, readwrite, assign) CGFloat borderWidth;
     
     @property (nonatomic, readwrite, assign) YGValue width;
     @property (nonatomic, readwrite, assign) YGValue height;
     @property (nonatomic, readwrite, assign) YGValue minWidth;
     @property (nonatomic, readwrite, assign) YGValue minHeight;
     @property (nonatomic, readwrite, assign) YGValue maxWidth;
     @property (nonatomic, readwrite, assign) YGValue maxHeight;
     
     // Yoga specific properties, not compatible with flexbox specification
     @property (nonatomic, readwrite, assign) CGFloat aspectRatio;
     
     /**
     Get the resolved direction of this node. This won't be YGDirectionInherit
     */
     @property (nonatomic, readonly, assign) YGDirection resolvedDirection;
     */
    @objc func flex(layout:Dictionary<String,String>) {
//        self.configureLayout { (lay) in
//            lay.isEnabled = true
//            if layout["flexDirection"] == "column" {
//                lay.flexDirection = YGFlexDirection.column
//            }
//            if layout["flexDirection"] == "row" {
//                lay.flexDirection = YGFlexDirection.row
//            }
//            if layout["justifyContent"] == "center" {
//                lay.justifyContent = YGJustify.center
//            }
//            if layout["alignItems"] == "stretch" {
//                lay.alignItems = YGAlign.stretch
//            }
//            if (layout["width"] != nil) {
//                if layout["width"]  == "auto" {
//                    lay.width = YGValueAuto
//                } else {
//                    lay.width = YGValue.init(value: 100, unit: YGUnit.point)
//                }
//            }
//            if (layout["height"] != nil) {
//                if layout["height"]  == "auto" {
//                    lay.height = YGValueAuto
//                } else {
//                    lay.height = YGValue.init(value: 50, unit: YGUnit.point)
//                }
//            }
//        }
        self.configureLayout { (lay) in
            lay.isEnabled = true
            if layout["flexDirection"] != nil {
                let value = layout["flexDirection"]!
                switch value {
                case "column":lay.flexDirection = YGFlexDirection.column
                case "row":lay.flexDirection = YGFlexDirection.row
                case "columnReverse":lay.flexDirection = YGFlexDirection.columnReverse
                case "rowReverse":lay.flexDirection = YGFlexDirection.rowReverse
                default:break
                }
            }
            /*
             YGJustifyFlexStart,
             YGJustifyCenter,
             YGJustifyFlexEnd,
             YGJustifySpaceBetween,
             YGJustifySpaceAround,
             YGJustifySpaceEvenly,
             */
            if layout["justifyContent"] != nil {
                let value = layout["justifyContent"]!
                switch value {
                case "start":lay.justifyContent = YGJustify.flexStart
                case "center":lay.justifyContent = YGJustify.center
                case "end":lay.justifyContent = YGJustify.flexEnd
                case "spaceBetween":lay.justifyContent = YGJustify.spaceBetween
                case "spaceAround":lay.justifyContent = YGJustify.center
                case "spaceEvenly":lay.justifyContent = YGJustify.center
                default:break
                }
            }
            
            
            if layout["justifyContent"] == "center" {
                lay.justifyContent = YGJustify.center
            }
            if layout["alignItems"] == "stretch" {
                lay.alignItems = YGAlign.stretch
            }
            if (layout["width"] != nil) {
                if layout["width"]  == "auto" {
                    lay.width = YGValueAuto
                } else {
                    let width = Float(layout["width"]!)
                    lay.width = YGValue.init(value: Float(width ?? 0), unit: YGUnit.point)
                }
            }
            if (layout["height"] != nil) {
                if layout["height"]  == "auto" {
                    lay.height = YGValueAuto
                } else {
                    let height = Float(layout["height"]!)
                    lay.height = YGValue.init(value: Float(height ?? 0), unit: YGUnit.point)
                }
            }
            
            if (layout["flexGrow"] != nil) {
                let flexGrow = Double(layout["flexGrow"]!)
                lay.flexGrow = CGFloat(flexGrow ?? 0);
            }
            
            if (layout["alignSelf"] == "center") {
                lay.alignSelf = YGAlign.center
            }
        }
    }
}
